package com.reebake.ideal.storage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.reebake.ideal.storage.entity.FileDetail;
import com.reebake.ideal.storage.entity.FileInfoDTO;
import com.reebake.ideal.storage.entity.FileListViewDTO;
import com.reebake.ideal.storage.exception.FlieNotSupportException;
import com.reebake.ideal.storage.service.FileDetailService;
import com.reebake.ideal.storage.service.FileOperationService;
import com.reebake.ideal.storage.util.StorageUtil;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.dromara.x.file.storage.core.get.ListFilesResult;
import org.dromara.x.file.storage.core.get.ListFilesSupportInfo;
import org.dromara.x.file.storage.core.get.RemoteDirInfo;
import org.dromara.x.file.storage.core.get.RemoteFileInfo;
import org.dromara.x.file.storage.core.platform.FileStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class FileOperationServiceImpl implements FileOperationService {
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private FileDetailService fileDetailService;

    private FileStorage getFileStorage(String platform) {
        if(StrUtil.isBlank(platform)) {
            return fileStorageService.getFileStorage();
        }
        return fileStorageService.getFileStorageVerify(platform);
    }

    private FileDetail query(String platform, String path, String filename) {
        LambdaQueryWrapper<FileDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrUtil.isNotBlank(platform), FileDetail::getPlatform, platform)
                .eq(StrUtil.isNotBlank(path), FileDetail::getPath, path)
                .eq(FileDetail::getFilename, filename);
        return fileDetailService.getOne(queryWrapper);
    }

    @Override
    public FileInfoDTO fileInfo(String url) {
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(url);
        return BeanUtil.copyProperties(fileInfo, FileInfoDTO.class);
    }

    @Override
    public FileInfoDTO fileInfo(String platform, String path, String filename) {
        FileDetail fileDetail = query(platform, path, filename);
        return BeanUtil.copyProperties(fileDetail, FileInfoDTO.class);
    }

    @Override
    public Boolean exists(String url) {
        return fileStorageService.exists(url);
    }

    @Override
    public Boolean exists(String platform, String path, String filename) {
        FileDetail fileDetail = query(platform, path, filename);
        return fileStorageService.exists(StorageUtil.toFileInfo(fileDetail));
    }

    @Override
    public void delete(String url) {
        fileStorageService.delete(url);
    }

    @Override
    public void delete(String platform, String path, String filename) {
        FileDetail fileDetail = query(platform, path, filename);
        fileStorageService.delete(StorageUtil.toFileInfo(fileDetail));
    }

    @Override
    public FileInfoDTO copy(String url, String platform, String path) {
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(url);
        FileInfo fileInfoCopy = fileStorageService.copy(fileInfo)
                .setPlatform(StrUtil.isNotBlank(platform), platform)
                .setPath(StrUtil.isNotBlank(path), path)
                .copy();
        return StorageUtil.toFileInfoDTO(fileInfoCopy);
    }

    @Override
    public FileInfoDTO move(String url, String platform, String path) {
        FileInfo fileInfo = fileStorageService.getFileInfoByUrl(url);
        FileInfo fileInfoMove = fileStorageService.move(fileInfo)
                .setPlatform(StrUtil.isNotBlank(platform), platform)
                .setPath(StrUtil.isNotBlank(path), path)
                .move();
        return StorageUtil.toFileInfoDTO(fileInfoMove);
    }

    @Override
    public FileListViewDTO list(String platform, String path, String marker, Integer maxFiles) {
        FileStorage fileStorage = getFileStorage(platform);
        ListFilesSupportInfo isSupportListFiles = fileStorage.isSupportListFiles();
        if(!isSupportListFiles.getIsSupport()) {
            throw new FlieNotSupportException();
        }
        //列举文件及目录
        ListFilesResult listFilesResult = fileStorageService.listFiles()
                .setPlatform(StrUtil.isNotBlank(platform), platform)
                .setPath(StrUtil.isNotBlank(path), path)
                .setMaxFiles(maxFiles != null, maxFiles)
                .setMarker(StrUtil.isNotBlank(marker), marker)
                .listFiles();

        return getListFiles(listFilesResult);
    }

    private static FileListViewDTO getListFiles(ListFilesResult listFilesResult) {
        FileListViewDTO listView = new FileListViewDTO();
        for(RemoteDirInfo remoteDirInfo : listFilesResult.getDirList()) {
            listView.getDirs().add(remoteDirInfo.getName());
        }
        for(RemoteFileInfo remoteFileInfo : listFilesResult.getFileList()) {
            listView.getFiles().add(remoteFileInfo.getFilename());
        }
        return listView;
    }
}
